package com.jdd.modules.system.controller;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.code.kaptcha.Producer;
import com.jdd.common.api.vo.Result;
import com.jdd.common.aspect.annotation.LogLevelType;
import com.jdd.common.aspect.annotation.OperationLogDetail;
import com.jdd.common.aspect.annotation.OperationType;
import com.jdd.common.aspect.annotation.OperationUnit;
import com.jdd.common.constant.CommonConstant;
import com.jdd.common.system.api.ISysBaseAPI;
import com.jdd.common.system.util.JwtUtil;
import com.jdd.common.system.vo.LoginUser;
import com.jdd.common.util.CacheUtil;
import com.jdd.common.util.LoginUserUtils;
import com.jdd.common.util.PasswordUtil;
import com.jdd.common.util.encryption.AesEncryptUtil;
import com.jdd.common.util.encryption.EncryptedString;
import com.jdd.common.util.encryption.RASUtil;
import com.jdd.common.util.oConvertUtils;
import com.jdd.modules.parking.entity.ParkInfo;
import com.jdd.modules.parking.mapper.ParkWorkStationMapper;
import com.jdd.modules.parking.service.IParkInfoService;
import com.jdd.modules.system.entity.SysUser;
import com.jdd.modules.system.model.SysLoginModel;
import com.jdd.modules.system.service.ISysLogService;
import com.jdd.modules.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URLDecoder;
import java.util.*;

/**
 * 用户登录控制器
 * @author
 */
@RestController
@RequestMapping("/sys")
@Api(tags="用户登录")
@Slf4j
public class LoginController {
    @Resource
	private ISysUserService sysUserService;
    @Resource
	private ISysBaseAPI sysBaseAPI;
    @Resource
	private ISysLogService logService;
    @Resource
	private Producer producer;
    @Resource
	private CacheUtil cacheUtil;
    @Resource
	private IParkInfoService parkInfoService;
    @Resource
	private ParkWorkStationMapper parkWorkStationMapper;

	public final static String KAPTCHA_REDIS_KEY = "KAPTCHA_SESSION_KEY";

	@Value("${jdd.login.captcha:true}")
	private boolean isNeedCaptcha;
	/**  手机端许可登录 */
	public static int SIGNMOBILEPRIMISSION = 1;
	public static String ILLEGALUSER = "该用户非法！";
	public static String SIGNMOBILEFORBID = "用户无手持端权限！";
	public static String IDORPASSWORDERROR = "用户名或密码错误！";
	public static String USERNOTEXIST = "用户名不存在！";
	public static String USERBEFREEZEN = "用户已冻结！";
	public static String USERBELOGOFF = "用户名已注销！";
	public  static String ADMINSBEFORBIDDEN = "最高管理员权限的超管用户禁止登录手持端!";
	public  static String PARKINGNOTEXIST = "用户分配的车场不存在!";
	public  static String NOPARKINGAPPOINT = "用户未分配车场!";
	public  static String MOREPARKINGBEFOUND = "用户拥有多个车场!";
	public  static String NOPARKINCODEEXIST = "车场无编号!";

	public static int RESULT500 = 500;

	@RequestMapping(value = "/getUserId",method = RequestMethod.GET)
	@ApiOperation("获取登陆人id")
	public Result<String> getUserId(){
		Result<String> result =new Result<String>();
		String id=null;
		try {
			id = LoginUserUtils.getLoginUser().getId();
			if(ObjectUtil.isNotEmpty(id)){
				result.setResult(id);
			}
		}catch (Exception e){
			result.error500("获取失败");
		}

		return result;
	}

	@RequestMapping(value = "/login", method = RequestMethod.POST)
	@ApiOperation("登录接口")
	@OperationLogDetail(detail ="登录",level= LogLevelType.ONE,operationType = OperationType.LOGIN,operationUnit = OperationUnit.USER)
	public Result<JSONObject> login(HttpServletRequest request, @RequestBody SysLoginModel sysLoginModel) throws Exception {
		Result<JSONObject> result;
		String username = sysLoginModel.getUsername();
		String oldpassword = sysLoginModel.getPassword().trim();
		String password = AesEncryptUtil.desEncrypt(URLDecoder.decode(oldpassword, CommonConstant.DEFAULT_CHARSET).replace(' ', '+'));
		if (StringUtils.isEmpty(password)) {
			password = oldpassword;
		}
		SysUser sysUser = sysUserService.getUserByName(username);
		result = sysUserService.checkUserIsEffective(sysUser);
		if (RESULT500 == result.getCode()) {
			return result;
		}
		// 校验用户是否有效
		if(!result.isSuccess()) {
			return result;
		}
		//校验数据的合法性
		if (StringUtils.isEmpty(sysUser.getSignature())) {
			result.error500("该用户非法");
			return result;
		}
		try{
			if(!RASUtil.verifySign(sysUser.getSignature(),sysUser.getUsername())) {
				result.error500("该用户非法");
				return result;
			}
		} catch (Exception e) {
			log.error("用户非法登录---> {}", e.getMessage());
			result.error500("该用户非法");
			return result;
		}
		//3. 校验用户名或密码是否正确
		String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt());
		String syspassword = sysUser.getPassword();
		if (!syspassword.equals(userpassword)) {
			result.error500("用户名或密码错误");
			return result;
		}
		//4.校验当前登录人是否有工作站且是在线状态的，如果符合则不让登录
//		List<ParkWorkStation> workStations = parkWorkStationMapper.getWorkStationByUserNameAndStatus(username, JddConstant.StringNumber.STRING_ONE);
//		if(ObjectUtil.isNotEmpty(workStations)){
//			result.error500("当前操作员在别处正在使用工作站查看监控");
//			return result;
//		}
		//用户登录信息
		userInfo(sysUser, result);
 		return result;
	}



	/**
	 * 退出登录
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/logout")
	public Result<Object> logout(HttpServletRequest request,HttpServletResponse response) {
		//用户退出逻辑
		Subject subject = SecurityUtils.getSubject();
		LoginUser sysUser = (LoginUser)subject.getPrincipal();
		//sysBaseAPI.addLog("用户名: "+sysUser.getRealname()+",退出成功！", CommonConstant.LOG_TYPE_1, null);
		log.info(" 用户名:  "+sysUser.getRealname()+",退出成功！ ");
		subject.logout();
		//清空用户Token缓存
//		redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + sysUser.getId());
		cacheUtil.delete(CommonConstant.TOKEN_CACHE_NAME, CommonConstant.PREFIX_USER_TOKEN + sysUser.getId());
		//清空用户权限缓存：权限Perms和角色集合
//		redisUtil.del(CommonConstant.LOGIN_USER_CACHERULES_ROLE + sysUser.getUsername());
		cacheUtil.delete(CommonConstant.TOKEN_CACHE_NAME, CommonConstant.LOGIN_USER_CACHERULES_ROLE + sysUser.getUsername());

//		redisUtil.del(CommonConstant.LOGIN_USER_CACHERULES_PERMISSION + sysUser.getUsername());
		cacheUtil.delete(CommonConstant.TOKEN_CACHE_NAME, CommonConstant.LOGIN_USER_CACHERULES_PERMISSION + sysUser.getUsername());

		return Result.ok("退出登录成功！");
	}

	/**
	 * 获取访问量
	 * @return
	 */
	@GetMapping("loginfo")
	public Result<JSONObject> loginfo() {
		Result<JSONObject> result = new Result<JSONObject>();
		JSONObject obj = new JSONObject();
		//update-begin--Author:zhangweijian  Date:20190428 for：传入开始时间，结束时间参数
		// 获取一天的开始和结束时间
		Calendar calendar = new GregorianCalendar();
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		Date dayStart = calendar.getTime();
		calendar.add(Calendar.DATE, 1);
		Date dayEnd = calendar.getTime();
		// 获取系统访问记录
		Long totalVisitCount = logService.findTotalVisitCount();
		obj.put("totalVisitCount", totalVisitCount);
		Long todayVisitCount = logService.findTodayVisitCount(dayStart,dayEnd);
		obj.put("todayVisitCount", todayVisitCount);
		Long todayIp = logService.findTodayIp(dayStart,dayEnd);
		//update-end--Author:zhangweijian  Date:20190428 for：传入开始时间，结束时间参数
		obj.put("todayIp", todayIp);
		result.setResult(obj);
		result.success("登录成功");
		return result;
	}

	/**
	 * 获取访问量
	 * @return
	 */
	@GetMapping("visitInfo")
	public Result<List<Map<String,Object>>> visitInfo() {
		Result<List<Map<String,Object>>> result = new Result<List<Map<String,Object>>>();
		Calendar calendar = new GregorianCalendar();
		calendar.set(Calendar.HOUR_OF_DAY,0);
		calendar.set(Calendar.MINUTE,0);
		calendar.set(Calendar.SECOND,0);
		calendar.set(Calendar.MILLISECOND,0);
		calendar.add(Calendar.DAY_OF_MONTH, 1);
		Date dayEnd = calendar.getTime();
		calendar.add(Calendar.DAY_OF_MONTH, -7);
		Date dayStart = calendar.getTime();
		List<Map<String,Object>> list = logService.findVisitCount(dayStart, dayEnd);
		result.setResult(oConvertUtils.toLowerCasePageList(list));
		return result;
	}


	/**
	 * 登陆成功选择用户当前部门
	 * @param user
	 * @return
	 */
	@RequestMapping(value = "/selectDepart", method = RequestMethod.PUT)
	public Result<?> selectDepart(@RequestBody SysUser user) {
		String username = user.getUsername();
		if(oConvertUtils.isEmpty(username)) {
			LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
			username = sysUser.getUsername();
		}
		String orgCode= user.getOrgCode();
		this.sysUserService.updateUserDepart(username, orgCode);
		return Result.ok();
	}





	/**
	 * 用户信息
	 *
	 * @param sysUser
	 * @param result
	 * @return
	 */
	private Result<JSONObject> userInfo(SysUser sysUser, Result<JSONObject> result) {
		String syspassword = sysUser.getPassword();
		String username = sysUser.getUsername();
		String userId = sysUser.getId();
		String parkCode = "";
		String parkName = "";

		// 获取车场信息
		List<ParkInfo> list = parkInfoService.list();
		if (!CollectionUtils.isEmpty(list)) {
			parkCode = list.get(0).getParkCode();
			parkName = list.get(0).getParkName();
		}
		// 生成token
		String token = JwtUtil.sign(username, userId, parkCode, parkName, syspassword);
//		redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + userId, token, JwtUtil.EXPIRE_TIME / 1000);
		cacheUtil.put(CommonConstant.TOKEN_CACHE_NAME, CommonConstant.PREFIX_USER_TOKEN + userId, token);
		// 获取用户部门信息
		JSONObject obj = new JSONObject();
		obj.put("token", token);
		obj.put("userInfo", sysUser);
		result.setResult(obj);
		result.success("登录成功");
		return result;
	}


	/**
	 * 获取加密字符串
	 * @return
	 */
	@GetMapping(value = "/getEncryptedString")
	public Result<Map<String,String>> getEncryptedString(){
        Result<Map<String, String>> result = new Result<>();
        Map<String, String> map = new HashMap<>(8);
        map.put("key", EncryptedString.key);
        map.put("iv", EncryptedString.iv);
        result.setResult(map);
        return result;
    }
	/**
	 * 获取本机mac
	 */
	private static String getLocalMac(InetAddress ia) throws SocketException {
		//获取网卡，获取地址
		byte[] mac = NetworkInterface.getByInetAddress(ia).getHardwareAddress();
		System.out.println("mac数组长度："+mac.length);
		StringBuffer sb = new StringBuffer("");
		for(int i=0; i<mac.length; i++) {
			if(i!=0) {
				sb.append("-");
			}
			//字节转换为整数
			int temp = mac[i]&0xff;
			String str = Integer.toHexString(temp);
			System.out.println("每8位:"+str);
			if(str.length()==1) {
				sb.append("0"+str);
			}else {
				sb.append(str);
			}
		}
		return sb.toString();
	}
}
